"""
LLM Configuration Utility
==========================
Centralizes LLM provider setup for all tutorial examples.
Supports OpenAI, Anthropic, and fallback to a mock LLM.

Usage:
    from src.utils.llm_config import get_llm
    llm = get_llm()  # Returns configured LLM
"""

import os
from dotenv import load_dotenv

load_dotenv()


def get_llm(provider: str = "openai", model: str = None, temperature: float = 0.7):
    """Get a configured LLM instance.
    
    Args:
        provider: "openai", "anthropic", or "mock"
        model: Model name (uses sensible defaults if None)
        temperature: Sampling temperature
    
    Returns:
        A LangChain chat model instance
    """
    if provider == "openai" and os.getenv("OPENAI_API_KEY"):
        from langchain_openai import ChatOpenAI
        return ChatOpenAI(
            model=model or "gpt-4o-mini",
            temperature=temperature,
            max_tokens=1000,
        )
    
    elif provider == "anthropic" and os.getenv("ANTHROPIC_API_KEY"):
        from langchain_anthropic import ChatAnthropic
        return ChatAnthropic(
            model=model or "claude-sonnet-4-20250514",
            temperature=temperature,
            max_tokens=1000,
        )
    
    else:
        # Fallback: Mock LLM for testing without API keys
        return MockLLM()


class MockLLM:
    """Mock LLM for testing without API keys.
    
    Returns deterministic responses based on input keywords.
    """
    
    def invoke(self, messages):
        """Process messages and return a mock response."""
        if isinstance(messages, list):
            last = messages[-1]
            content = last.content if hasattr(last, 'content') else str(last)
        else:
            content = str(messages)
        
        from langchain_core.messages import AIMessage
        return AIMessage(content=f"[Mock LLM] Processed: {content[:100]}")
    
    def bind_tools(self, tools):
        """Mock tool binding."""
        return self
    
    def __or__(self, other):
        """Support pipe operator."""
        return self


def get_embeddings(model_name: str = "all-MiniLM-L6-v2"):
    """Get an embedding model."""
    try:
        from sentence_transformers import SentenceTransformer
        return SentenceTransformer(model_name)
    except ImportError:
        print("Install sentence-transformers: pip install sentence-transformers")
        return None
